package com.whc.gulimall.product.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whc.common.constant.ProductConstant;
import com.whc.common.utils.PageUtils;
import com.whc.common.utils.Query;
import com.whc.common.utils.RRException;
import com.whc.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.whc.gulimall.product.dao.AttrDao;
import com.whc.gulimall.product.dao.AttrGroupDao;
import com.whc.gulimall.product.dao.CategoryDao;
import com.whc.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.whc.gulimall.product.entity.AttrEntity;
import com.whc.gulimall.product.entity.AttrGroupEntity;
import com.whc.gulimall.product.entity.CategoryEntity;
import com.whc.gulimall.product.service.AttrService;
import com.whc.gulimall.product.service.CategoryService;
import com.whc.gulimall.product.vo.AttrRespVo;
import com.whc.gulimall.product.vo.AttrVo;
import com.whc.gulimall.product.vo.CategoryPathDto;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author angaoen
 */
@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    /**
     * 商品三级分类 Dao
     */
    @Resource
    private CategoryDao categoryDao;

    /**
     * 属性&属性分组关联 Dao
     */
    @Resource
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;

    /**
     * 属性分组 Dao
     */
    @Resource
    private AttrGroupDao attrGroupDao;

    /**
     * 商品三级分类 Service
     */
    @Resource
    private CategoryService categoryService;

    /**
     * 商品属性 Dao
     */
    @Resource
    private AttrDao attrDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<>()
        );

        return new PageUtils(page);
    }

    /**
     * 保存属性
     *
     * @param attr 属性
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAttr(AttrVo attr) {
        // 先保存属性数据到数据库
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr, attrEntity);
        baseMapper.insert(attrEntity);

        if (attr.getAttrType().equals(ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())
                && attr.getAttrGroupId() != null) {
            // 保存关联表数据
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
            attrAttrgroupRelationEntity.setAttrId(attrEntity.getAttrId());
            attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
            attrAttrgroupRelationDao.insert(attrAttrgroupRelationEntity);
        }
    }

    /**
     * 分页查询数据
     *
     * @param params 参数
     * @param catId  分类id
     * @param type   属性类型
     * @return 分页数据
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params, Long catId, String type) {
        // 获取到查询类型
        int code = "base".equalsIgnoreCase(type)
                ? ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()
                : ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode();
        // 获取查询条件
        String key = (String) params.get("key");
        // 封装基础查询条件
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>().eq("attr_type", code);
        if (StringUtils.hasText(key)) {
            wrapper.and(obj -> obj.eq("attr_id", key).or().like("attr_name", key));
        }
        if (!catId.equals(0L)) {
            wrapper.eq("catelog_id", catId);
        }
        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params), wrapper);
        PageUtils pageUtils = new PageUtils(page);
        // 获取到查询出的初始数据
        List<AttrEntity> attrEntities = page.getRecords();
        // 判空
        if (!CollectionUtils.isEmpty(attrEntities)) {
            // 封装好返回给前端需要的数据集合
            List<AttrRespVo> attrRespVos = attrEntities.stream().map(item -> {
                AttrRespVo attrRespVo = new AttrRespVo();
                BeanUtils.copyProperties(item, attrRespVo);
                return attrRespVo;
            }).collect(Collectors.toList());
            // 获取属性id集合
            List<Long> attrIds = attrEntities.stream().map(AttrEntity::getAttrId).collect(Collectors.toList());
            // 条件判断
            if (!CollectionUtils.isEmpty(attrIds) && code != ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode()) {
                // 获取分类分组属性集合
                List<AttrAttrgroupRelationEntity> attrgroupRelationEntities = attrAttrgroupRelationDao
                        .selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_id", attrIds));
                if (!CollectionUtils.isEmpty(attrgroupRelationEntities)) {
                    // 封装出分组id和分组id的map集合
                    Map<Long, Long> attrgroupRelationMap = attrgroupRelationEntities.stream()
                            .collect(Collectors.toMap(AttrAttrgroupRelationEntity::getAttrId,
                                    AttrAttrgroupRelationEntity::getAttrGroupId));
                    if (!CollectionUtils.isEmpty(attrgroupRelationMap)) {
                        // 设置分组id
                        attrRespVos.forEach(item -> item.setAttrGroupId(attrgroupRelationMap.get(item.getAttrId())));
                    }
                }
            }

            // 获取分类id
            List<Long> categoryIds = attrEntities.stream().map(AttrEntity::getCatelogId).collect(Collectors.toList());
            // 判空
            if (!CollectionUtils.isEmpty(categoryIds)) {
                // 封装分类数据
                List<CategoryEntity> categoryEntities = categoryDao.selectBatchIds(categoryIds);
                Map<Long, String> categoryMap = categoryEntities.stream()
                        .collect(Collectors.toMap(CategoryEntity::getCatId, CategoryEntity::getName));
                // 设置catelogName
                if (!CollectionUtils.isEmpty(categoryMap)) {
                    attrRespVos.forEach(item -> item.setCatelogName(categoryMap.get(item.getCatelogId())));
                }

                // 获取到分类分组数据
                List<AttrGroupEntity> attrGroupEntities = attrGroupDao
                        .selectList(new QueryWrapper<AttrGroupEntity>().in("catelog_id", categoryIds));
                if (!CollectionUtils.isEmpty(attrGroupEntities)) {
                    // 获取到分组数据map
                    Map<Long, String> attrGroupMap = attrGroupEntities.stream().collect(Collectors
                            .toMap(AttrGroupEntity::getAttrGroupId, AttrGroupEntity::getAttrGroupName));
                    // 设置groupName
                    if (!CollectionUtils.isEmpty(attrGroupMap)) {
                        attrRespVos.forEach(item -> item.setGroupName(attrGroupMap.get(item.getAttrGroupId())));
                    }
                }
            }
            pageUtils.setList(attrRespVos);
        }
        return pageUtils;
    }

    /**
     * 通过属性id获取到attr属性信息
     *
     * @param attrId 属性id
     * @return 数据
     */
    @Override
    public AttrRespVo getInfoById(Long attrId) {
        AttrEntity attrEntity = baseMapper.selectById(attrId);
        if (attrEntity != null) {
            AttrRespVo respVo = new AttrRespVo();
            // 属性对拷
            BeanUtils.copyProperties(attrEntity, respVo);

            if (attrEntity.getAttrType().equals(ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())) {
                // 获取分组id
                AttrAttrgroupRelationEntity relationEntity = attrAttrgroupRelationDao
                        .selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
                if (relationEntity != null) {
                    Long attrGroupId = relationEntity.getAttrGroupId();
                    respVo.setAttrGroupId(attrGroupId);
                    // 设置分组名称
                    AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrGroupId);
                    if (attrGroupEntity != null) {
                        respVo.setGroupName(attrGroupEntity.getAttrGroupName());
                    }
                }
            }

            Long catelogId = attrEntity.getCatelogId();
            if (catelogId != null && !catelogId.equals(0L)) {
                // 获取三级分类id
                CategoryPathDto categoryPathDto = categoryService.getCategoryPathById(catelogId);
                ArrayList<Long> categoryPath = new ArrayList<>(3);
                categoryPath.add(categoryPathDto.getFirCategory());
                categoryPath.add(categoryPathDto.getSecCategory());
                categoryPath.add(categoryPathDto.getTirCategory());
                respVo.setCatelogPath(categoryPath);
            }
            return respVo;
        }
        return null;
    }

    /**
     * 根据id更新属性
     *
     * @param attr 属性
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateInfoById(AttrVo attr) {
        Long attrId = attr.getAttrId();
        AttrEntity attrEntity = baseMapper.selectById(attrId);
        if (attrEntity == null) {
            throw new RRException("无此属性数据");
        }
        // 更新基本信息
        BeanUtils.copyProperties(attr, attrEntity);
        baseMapper.updateById(attrEntity);

        // 只有基本属性有属性分组
        if (attr.getAttrType().equals(ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())) {
            // 判断是新增还是修改
            Integer count = attrAttrgroupRelationDao
                    .selectCount(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
            attrAttrgroupRelationEntity.setAttrId(attrId);
            attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
            if (count > 0) {
                // 修改操作
                attrAttrgroupRelationDao.update(attrAttrgroupRelationEntity,
                        new UpdateWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
            } else {
                // 新增操作
                attrAttrgroupRelationDao.insert(attrAttrgroupRelationEntity);
            }
        }
    }

    /**
     * 获取属性分组的关联的所有属性
     *
     * @param attrgroupId 属性分组id
     * @return 统一返回结果
     */
    @Override
    public List<AttrEntity> getRelationAttr(Long attrgroupId) {
        // 根据attr_group_id获取到pms_attr_attrgroup_relation中对应的所有的attr_id
        List<AttrAttrgroupRelationEntity> attrgroupRelationEntities = attrAttrgroupRelationDao
                .selectList(new QueryWrapper<AttrAttrgroupRelationEntity>()
                        .eq("attr_group_id", attrgroupId));

        // 判空
        if (CollUtil.isNotEmpty(attrgroupRelationEntities)) {
            // 获取到所有的attrId
            List<Long> attrIds = attrgroupRelationEntities.stream().map(AttrAttrgroupRelationEntity::getAttrId)
                    .collect(Collectors.toList());
            // 根据attrId获取到对应的attr属性
            return CollectionUtils.isEmpty(attrIds) ? null : attrDao.selectBatchIds(attrIds);
        }
        return null;
    }

    /**
     * 通过商品所拥有的属性id在pms_attr表中获取到可被检索的属性
     *
     * @param attrIds    属性id列表
     * @param searchType 检索
     * @return 可被检索的属性列表ids
     */
    @Override
    public List<Long> listSearchAttrIdsByAttrIds(List<Long> attrIds, Integer searchType) {
        return baseMapper.listSearchAttrIdsByAttrIds(attrIds, searchType);
    }
}
